package org.freedesktop.forcefeedback;

import android.util.Log;
import android.view.KeyEvent;

import com.hqumath.androidnative.app.Constant;
import com.hqumath.androidnative.tools.GameDevice;
import com.jeremyliao.liveeventbus.LiveEventBus;

/**
 * Force feedback support for Logitech Gaming Wheels
 */
public class ForceFeedback {
    ////////////////////////////////////native///////////////////////////////////
    static {
        System.loadLibrary("force_feedback");
    }

    /**
     * 查找设备,更新当前设备
     * 遍历文件=>读取id=>找到指定设备
     *
     * @return -1未找到 1已找到
     */
    private native int findDevice();

    /**
     * 连接并读取当前设备
     * 打开当前设备文件=>设置参数_=>持续读取
     *
     * @return -1失败 1成功
     */
    private native int connectAndReadDevice();

    /**
     * 断开连接
     * 停止读取=>清空设置=>关闭文件
     *
     * @return -1失败 1成功
     */
    private native int disconnectDevice();

    /**
     * 获取当前设备id
     *
     * @return 例如：046d:c24f
     */
    public native String getDeviceId();

    /**
     * 获取当前设备文件描述符
     *
     * @return 例如：23 , >0表示已连接设备
     */
    private native int getDeviceFd();

    /**
     * 设置回中力
     *
     * @param value∈[0,1]
     * @return -1失败 1成功
     */
    public native int setAutoCenter(float value);

    /**
     * 设置常力
     *
     * @param value∈[-1,1] -1左满，1右满
     * @return -1失败 1成功
     */
    public native int setConstant(float value);

    /**
     * 设置增益
     *
     * @param value∈[0,1]
     * @return -1失败 1成功
     */
    public native int setGain(float value);

    /**
     * 查询设备能力
     *
     * @return
     */
    public native int queryDeviceCapabilities();

    /**
     * c层回调，方向盘事件
     *
     * @param type
     * @param code
     * @param value
     */
    private void readInputEvent(int type, int code, int value) {
        String deviceId = getDeviceId();
        String msg = String.format("Event: type %d, code %d,value %d", type, code, value);
        Log.d(TAG, msg);
        //罗技G29 PS3模式
        /*if (type == 0x03) {//EV_ABS 绝对轴值变化
            switch (code) {
                case 0://转向
                    float turnF = value / 32767.5f - 1;//转向范围[0,65535] => [-1,1]
                    if (Math.abs(turnF) < 0.08f) {//踏板可能不干净,丢弃一些接近0的数据
                        turnF = 0f;
                    }
                    GameDevice.setTurn(turnF);
                    break;
                case 1://离合
                    float clutchF = 1 - value / 255f;//离合范围[255,0] => [0,1]
                    if (Math.abs(clutchF) < 0.08f) {
                        clutchF = 0f;
                    }
                    GameDevice.setClutch(clutchF);
                    break;
                case 2://油门
                    float gasF = 1 - value / 255f;//油门范围[255,0] => [0,1]
                    if (Math.abs(gasF) < 0.08f) {
                        gasF = 0f;
                    }
                    GameDevice.setGas(gasF);
                    break;
                case 5://刹车
                    float brakeF = 1 - value / 255f;//刹车范围[255,0] => [0,1]
                    //踏板可能不干净,丢弃一些接近0的数据
                    if (Math.abs(brakeF) < 0.08f) {
                        brakeF = 0f;
                    }
                    GameDevice.setBrake(brakeF);
                    break;
                case 16://左右
                    if (value == -1) {
                        GameDevice.clickKey(KeyEvent.KEYCODE_DPAD_LEFT);//导航键 方向
                    } else if (value == 1) {
                        GameDevice.clickKey(KeyEvent.KEYCODE_DPAD_RIGHT);
                    } else if (value == 0) {
                        //松开
                    }
                    break;
                case 17://上下
                    if (value == -1) {
                        GameDevice.clickKey(KeyEvent.KEYCODE_DPAD_UP);
                    } else if (value == 1) {
                        GameDevice.clickKey(KeyEvent.KEYCODE_DPAD_DOWN);
                    } else if (value == 0) {
                        //松开
                    }
                    break;
            }
        } else if (type == 0x01) {//EV_KEY 按键状态变化
            if (value == 1) {//按下
                switch (code) {
                    case 288://x
                        GameDevice.clickKey(KeyEvent.KEYCODE_DPAD_CENTER);//导航键 确定
                        break;
                    case 289://□
                        LiveEventBus.get(Constant.WHEEL_KEY).post(Constant.WHEEL_SQUARE);
                        break;
                    case 290://○
                        GameDevice.clickKey(KeyEvent.KEYCODE_BACK);//导航键 返回
                        break;
                    case 291://△
                        LiveEventBus.get(Constant.WHEEL_KEY).post(Constant.WHEEL_TRIANGLE);
                        break;
                    case 292://右拨片
                        LiveEventBus.get(Constant.WHEEL_KEY).post(Constant.SHIFT_RIGHT);
                        break;
                    case 293://左拨片
                        LiveEventBus.get(Constant.WHEEL_KEY).post(Constant.SHIFT_LEFT);
                        break;
                    case 294://R2
                        LiveEventBus.get(Constant.WHEEL_KEY).post(Constant.WHEEL_R2);
                        break;
                    case 295://L2
                        LiveEventBus.get(Constant.WHEEL_KEY).post(Constant.WHEEL_L2);
                        break;
                    case 296://SHARE
                        LiveEventBus.get(Constant.WHEEL_KEY).post(Constant.WHEEL_SHARE);
                        break;
                    case 297://OPTION
                        LiveEventBus.get(Constant.WHEEL_KEY).post(Constant.WHEEL_OPTION);
                        break;
                    case 298://R3
                        LiveEventBus.get(Constant.WHEEL_KEY).post(Constant.WHEEL_R3);
                        break;
                    case 299://L3
                        LiveEventBus.get(Constant.WHEEL_KEY).post(Constant.WHEEL_L3);
                        break;
                    case 300://一挡
                        LiveEventBus.get(Constant.WHEEL_KEY).post(Constant.GEAR_1);
                        break;
                    case 301://二挡
                        LiveEventBus.get(Constant.WHEEL_KEY).post(Constant.GEAR_2);
                        break;
                    case 302://三挡
                        LiveEventBus.get(Constant.WHEEL_KEY).post(Constant.GEAR_3);
                        break;
                    case 303://四挡
                        LiveEventBus.get(Constant.WHEEL_KEY).post(Constant.GEAR_4);
                        break;
                    case 704://五挡
                        LiveEventBus.get(Constant.WHEEL_KEY).post(Constant.GEAR_5);
                        break;
                    case 705://倒挡
                        LiveEventBus.get(Constant.WHEEL_KEY).post(Constant.GEAR_R);
                        break;
                    case 707://增加
                        LiveEventBus.get(Constant.WHEEL_KEY).post(Constant.ADD);
                        break;
                    case 708://减少
                        LiveEventBus.get(Constant.WHEEL_KEY).post(Constant.SUBTRACT);
                        break;
                    case 709://确认右转
                        LiveEventBus.get(Constant.WHEEL_KEY).post(Constant.CONFIRM_RIGHT);
                        break;
                    case 710://确认左转
                        LiveEventBus.get(Constant.WHEEL_KEY).post(Constant.CONFIRM_LEFT);
                        break;
                    case 711://确认
                        LiveEventBus.get(Constant.WHEEL_KEY).post(Constant.CONFIRM);
                        break;
                    case 712://PLAYSTATION
                        LiveEventBus.get(Constant.WHEEL_KEY).post(Constant.PLAY_STATION_DOWN);
                        break;
                }
            } else if (value == 0) {//松开
                switch (code) {
                    case 300://一挡
                    case 301://二挡
                    case 302://三挡
                    case 303://四挡
                    case 704://五挡
                    case 705://倒挡
                        LiveEventBus.get(Constant.WHEEL_KEY).post(Constant.GEAR_0);//空挡
                        break;
                    case 712://PLAYSTATION
                        LiveEventBus.get(Constant.WHEEL_KEY).post(Constant.PLAY_STATION_UP);
                        break;
                }
            }
        }*/
    }

    ////////////////////////////////////java///////////////////////////////////
    private final String TAG = "ForceFeedback";

    //静态内部类
    private static class ForceFeedbackHolder {
        private static final ForceFeedback instance = new ForceFeedback();
    }

    public static ForceFeedback getInstance() {
        return ForceFeedbackHolder.instance;
    }

    //查找并连接设备
    public void findAndConnect() {
        Log.d(TAG, "查找设备");
        int fd = getDeviceFd();
        if (fd > 0) {//已连接设备
            return;
        }
        int result = findDevice();
        if (result > 0) {
            Log.d(TAG, "连接设备");
            connectAndReadDevice();
        } else {
            Log.d(TAG, "未找到设备");
        }
    }

    //断开连接
    public void disconnect() {
        disconnectDevice();
    }
}
